package cn.org.timespace.easyframe.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;

/**
 * 算术工具类
 * 
 * @author javen
 * @version $Revision: 1.1 $ $Date: 2010/06/19 14:32:10 $
 */

public class MathUtils {
    //默认除法运算精度
    private static final int DEF_DIV_SCALE = 10;

    //这个类不能实例化
    private MathUtils() {
    }
    /**
     * 提供精确的加法运算。
     * 
     * @param v1
     *                    被加数
     * @param v2
     *                    加数
     * @return 两个参数的和
     */
    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     * 
     * @param v1
     *                    被减数
     * @param v2
     *                    减数
     * @return 两个参数的差
     */
    public static double sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算。
     * 
     * @param v1
     *                    被乘数
     * @param v2
     *                    乘数
     * @return 两个参数的积
     */
    public static double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供（相对）精确的除法运算，当发生除不尽的情况时，精确到 小数点以后10位，以后的数字四舍五入。
     * 
     * @param v1
     *                    被除数
     * @param v2
     *                    除数
     * @return 两个参数的商
     */
    public static double div(double v1, double v2) {
        return div(v1, v2, DEF_DIV_SCALE);
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指 定精度，以后的数字四舍五入。
     * 
     * @param v1
     *                    被除数
     * @param v2
     *                    除数
     * @param scale
     *                    表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    
    /**
     * 提供精确的小数位四舍五入处理。
     * 
     * @param v
     *                    需要四舍五入的数字
     * @param scale
     *                    小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale) {
    	if(scale<0){   
    		  
    		throw new IllegalArgumentException(   
    		  
    		"The scale must be a positive integer or zero");   
    		  
    		}   
    		  
    		BigDecimal b = new BigDecimal(Double.toString(v));   
    		  
    		BigDecimal one = new BigDecimal("1");   
    		  
    		return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();  
    }
    /**
     * 提供精确的小数位三舍四入处理。
     * 
     * @param v     需要三舍四入的数字
     * @return   三舍四入后的结果
     */
    public static double round34(double v) {
    	
    	 double v2=0.01;
    	 v=MathUtils.round(v,2);
		 return round(MathUtils.add(v, v2),1); 
	}
    
    /** 
	 * 保留小数后两位
	 * @param number
	 * @return
	 */
	public static String convNumber(double number)
	   {
	     DecimalFormat df1=new DecimalFormat("0.00");
	     String str=df1.format(number);
	     return str;
	   }
	/**
	 * 将String形式的钱格式化为money的形式

	 */

    public static String formatToMoney(String s) {
        if (s == null || s.equals("")) {
            return "0.00";
        }
        try {
            return formatToMoney(Double.parseDouble(s));
        } catch (Exception e) {
            return s;
        }
    }
	/**
	 * 将double形式的钱格式化为money的形式
	 * @param d
	 * @return 例如:1,137.00
	 */
    public static String formatToMoney(double d) {
    	DecimalFormat nf = new DecimalFormat("###,##0.00");
        try {
            return nf.format(d);
        } catch (Exception e) {
            return String.valueOf(d);
        }
    }
    
    
	/**
	 * 将double形式的钱格式化为money的形式
	 * @param d
	 * @return 例如:191137.00
	 */   
    public static String formatToMoney2(double d) {
    	DecimalFormat nf = new DecimalFormat("###0.00");
        try {
            return nf.format(d);
        } catch (Exception e) {
            return String.valueOf(d);
        }
    }
    

	/**
	 * 获取集合list中的最大数字并返回
	 * @param list
	 * @return 例如:191137.00
	 */ 
	public static Long getMaxNumFromNumList(List<Long> list){
		Long rs = list.get(0);
		
		for(Long i:list){
			if(i>rs)
				rs = i;
		}
		
		return rs;
	}
}
